package fr.mywiki.business.login;

import java.rmi.RemoteException;

import junit.framework.Test;
import junit.framework.TestSuite;
import servletunit.struts.CactusStrutsTestCase;
import fr.mywiki.business.account.AccountLite;
import fr.mywiki.business.login.LoginManager;
import fr.mywiki.business.navigation.NavigationManager;
import fr.mywiki.business.profil.Profile;
import fr.mywiki.model.ejbAdapter.DataController;
import fr.mywiki.test.utils.ConnectFactory;
import fr.mywiki.test.utils.factory.AccountFactory;

/**
 * Test class for LoginManager.
 * 
 * @see http://localhost:8080/MyWiki/ServletTestRunner?suite=fr.mywiki.business.login.LoginManagerTest&xsl=cactus-report.xsl
 */
public class LoginManagerTest extends CactusStrutsTestCase {
	public LoginManagerTest(String a_name) {
		super(a_name);
	}

	public static Test suite() {
		TestSuite suite = new TestSuite();
		suite.addTestSuite(LoginManagerTest.class);

		return suite;
	}
	
	/** Tests the function getLoggedUser in case there is no logged user. */
	public void testAnonymousGetLoggedUser() {
		assertNull(LoginManager.getLoggedUser(session));
		assertFalse(LoginManager.hasLoggedUser(session));
	}

	/** Tests the function getLoggedUser in case the logged user is a known user. */
	public void testKnownGetLoggedUser() {
		try {
			ConnectFactory.loginAdminUser(session);
		} catch (RemoteException e) {
			fail("Login admin");
		}

		AccountLite admin = null;
		try {
			admin = (AccountLite) DataController.getValue(new Long(0),
					AccountLite.TYPE_ENT);
		} catch (RemoteException e) {
			fail("Get admin user");
		}

		assertEquals(admin, LoginManager.getLoggedUser(session));
		assertTrue(LoginManager.hasLoggedUser(session));
	}

	/**
	 * Test of initSession method. Connects a user and tests if he is connected
	 * after, tests the initialized spaces.
	 */
	public void testInitSession() {
		assertFalse(LoginManager.hasLoggedUser(session));
		assertEquals(Profile.ANONYMOUS.getSpaces(), NavigationManager
				.getSpaces(session));

		try {
			LoginManager.initSession(session, AccountFactory.getAnyAccount());
		} catch (RemoteException e) {
			fail("Get any account");
		}

		assertTrue(LoginManager.hasLoggedUser(session));
		assertNotNull(NavigationManager.getSpaces(session));
		assertEquals(Profile.ADMIN.getSpaces(), NavigationManager
				.getSpaces(session));
	}

	/** Tests correct login. */
	public void testLoginCorrect() {
		assertFalse(LoginManager.hasLoggedUser(session));

		String retour = LoginManager.login("admin", "a", session);
		assertEquals(LoginManager.CONNECTION_OK, retour);

		assertTrue(LoginManager.hasLoggedUser(session));
	}

	/** Tests login with null login. */
	public void testLoginNullLogin() {
		assertFalse(LoginManager.hasLoggedUser(session));

		String retour = LoginManager.login(new String(), "a", session);
		assertEquals(LoginManager.NULL_LOGIN, retour);

		assertFalse(LoginManager.hasLoggedUser(session));
	}

	/** Tests login with null password. */
	public void testLoginNullPassword() {
		assertFalse(LoginManager.hasLoggedUser(session));

		String retour = LoginManager.login("admin", "", session);
		assertEquals(LoginManager.NULL_PASSWORD, retour);

		assertFalse(LoginManager.hasLoggedUser(session));
	}
	
	/** Tests login with invalid login. */
	public void testLoginNotFound() {
		assertFalse(LoginManager.hasLoggedUser(session));

		String retour = LoginManager.login("sdfhjkshqfkjqshflqhsdjfhqskjdlf", "a", session);
		assertEquals(LoginManager.USER_NOT_FOUND, retour);

		assertFalse(LoginManager.hasLoggedUser(session));
	}
	
	/** Tests login with invalid login. */
	public void testLoginBadPassword() {
		assertFalse(LoginManager.hasLoggedUser(session));

		String retour = LoginManager.login("admin", "b", session);
		assertEquals(LoginManager.UNCORRECT_PASSWORD, retour);

		assertFalse(LoginManager.hasLoggedUser(session));
	}
	
	/** Tests logout method */
	public void testLogout() {
		assertFalse(LoginManager.hasLoggedUser(session));
		
		String retour = LoginManager.login("admin", "a", session);
		assertEquals(LoginManager.CONNECTION_OK, retour);

		assertTrue(LoginManager.hasLoggedUser(session));
		
		LoginManager.logout(session);
		
		assertFalse(LoginManager.hasLoggedUser(session));
	}
}
